package com.yfjin.fbus;

import android.content.Context;
import android.util.Log;

import com.google.gson.Gson;
import com.yfjin.fbus.annotion.ClassId;
import com.yfjin.fbus.request.RequestBean;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;

public class IpcNameManager {


    private final static IpcNameManager mInstance = new IpcNameManager();
    private final static Gson GSON=new Gson();

    public static IpcNameManager getDefault() {
        return mInstance;
    }


    private Context mContext;
    private NameCenter mNameCenter = new NameCenter();

    public void init(Context context) {
        mContext = context.getApplicationContext();
    }

    public NameCenter getNameCenter() {
        return mNameCenter;
    }

    public void register(Class<?> clazz) {
        mNameCenter.register(clazz);
    }


    public void connect(String ip) {
        new Thread(() -> connectServerIp(ip)).start();
    }


    ProjectSocketClient mProjetClient;

    private void connectServerIp(String ip) {
        try {
            URI url = new URI("ws://" + ip + ":" + NameServerManager.PORT);
            mProjetClient = new ProjectSocketClient(url);
            mProjetClient.connect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //    服务 发现
    public <T> T getInstance(Class<T> clazz, Object... parameters) {

        sendRequest(clazz, null, parameters, NameServerManager.TYPE_GET);

        return getProxy(clazz);
    }

    private <T> void sendRequest(Class<T> clazz, Method method, Object[] parameters, int type) {
        RequestBean.RequestParamter[] requestParamterArry = null;
        if (parameters != null && parameters.length > 0) {
            requestParamterArry = new RequestBean.RequestParamter[parameters.length];

            for (int i = 0; i < parameters.length; i++) {
                Object p = parameters[i];
                String name = p.getClass().getName();
                String value = GSON.toJson(p);
                RequestBean.RequestParamter requestParamter = new RequestBean.RequestParamter();
                requestParamter.setParameterClassName(name);
                requestParamter.setParameterValue(value);
                requestParamterArry[i] = requestParamter;
            }
        }

        String className = clazz.getAnnotation(ClassId.class).value();
        String methodName = method == null ? "getInstance" : method.getName();
        RequestBean requestBean = new RequestBean(type, className, methodName, requestParamterArry);
        String requt = GSON.toJson(requestBean);
        mProjetClient.send(requt.getBytes());
    }

    private <T> T getProxy(Class<T> clazz) {
        ClassLoader classLoader = mContext.getClassLoader();

        return (T) Proxy.newProxyInstance(classLoader, new Class<?>[]{clazz}, new NameServerInvocationHandler(clazz));
    }


    static class ProjectSocketClient extends WebSocketClient {
        public ProjectSocketClient(URI serverUri) {
            super(serverUri);
        }

        @Override
        public void onOpen(ServerHandshake handshakedata) {
            Log.i("123123", "client :onOpen" );
        }

        @Override
        public void onMessage(String message) {
        }

        @Override
        public void onClose(int code, String reason, boolean remote) {
        }

        @Override
        public void onError(Exception ex) {
        }
    }
}
